home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume13 / gmcalc / part03 < prev    next >
Encoding:
Text File  |  1990-06-05  |  57.7 KB  |  1,780 lines

  1. Newsgroups: comp.sources.misc
  2. From: daveg@csvax.caltech.edu (David Gillespie)
  3. Subject: v13i029: Emacs Calculator 1.01, part 03/19
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 13, Issue 29
  7. Submitted-by: daveg@csvax.caltech.edu (David Gillespie)
  8. Archive-name: gmcalc/part03
  9.  
  10. ---- Cut Here and unpack ----
  11. #!/bin/sh
  12. # this is part 3 of a multipart archive
  13. # do not concatenate these parts, unpack them in order with /bin/sh
  14. # file calc.el continued
  15. #
  16. CurArch=3
  17. if test ! -r s2_seq_.tmp
  18. then echo "Please unpack part 1 first!"
  19.      exit 1; fi
  20. ( read Scheck
  21.   if test "$Scheck" != $CurArch
  22.   then echo "Please unpack part $Scheck next!"
  23.        exit 1;
  24.   else exit 0; fi
  25. ) < s2_seq_.tmp || exit 1
  26. echo "x - Continuing file calc.el"
  27. sed 's/^X//' << 'SHAR_EOF' >> calc.el
  28. X            0)))
  29. X    (math-make-float (math-quotient (math-scale-int (nth 1 a) ldiff) (nth 1 b))
  30. X             (- (- (nth 2 a) (nth 2 b)) ldiff)))
  31. X)
  32. X
  33. X(defun math-inv (m)
  34. X  (if (Math-vectorp m)
  35. X      (progn
  36. X    (calc-extensions)
  37. X    (if (math-square-matrixp m)
  38. X        (or (math-with-extra-prec 2 (math-matrix-inv-raw m))
  39. X        (math-reject-arg m "Singular matrix"))
  40. X      (math-reject-arg m 'square-matrixp)))
  41. X    (math-div 1 m))
  42. X)
  43. X(fset 'calcFunc-inv (symbol-function 'math-inv))
  44. X
  45. X
  46. X(defmacro math-working (msg arg)    ; [Public]
  47. X  (` (if (eq calc-display-working-message 'lots)
  48. X     (progn
  49. X       (calc-set-command-flag 'clear-message)
  50. X       (message "Working... %s = %s"
  51. X            (, msg)
  52. X            (math-showing-full-precision
  53. X             (math-format-number (, arg)))))))
  54. X)
  55. X
  56. X
  57. X;;; Compute A modulo B, defined in terms of truncation toward minus infinity.
  58. X(defun math-mod (a b)   ; [R R R] [Public]
  59. X  (cond ((Math-zerop a) a)
  60. X    ((Math-zerop b)
  61. X     (math-reject-arg a "Division by zero"))
  62. X    ((and (Math-natnump a) (Math-natnump b))
  63. X     (math-imod a b))
  64. X    ((and (Math-anglep a) (Math-anglep b))
  65. X     (math-sub a (math-mul (math-floor (math-div a b)) b)))
  66. X    ((and (eq (car-safe a) 'mod) (Math-realp b) (math-posp b))
  67. X     (math-make-mod (nth 1 a) b))
  68. X    ((and (eq (car-safe a) 'intv) (math-constp a) (math-posp b))
  69. X     (math-mod-intv a b))
  70. X    (t
  71. X     (if (Math-anglep a)
  72. X         (calc-record-why 'anglep b)
  73. X       (calc-record-why 'anglep a))
  74. X     (list '% a b)))
  75. X)
  76. X(defun calcFunc-mod (a b)
  77. X  (math-normalize (list '% a b))
  78. X)
  79. X
  80. X
  81. X;;; Compute the greatest common divisor of A and B.   [I I I] [Public]
  82. X(defun math-gcd (a b)
  83. X  (cond
  84. X   ((not (or (consp a) (consp b)))
  85. X    (if (< a 0) (setq a (- a)))
  86. X    (if (< b 0) (setq b (- b)))
  87. X    (let (c)
  88. X      (if (< a b)
  89. X      (setq c b b a a c))
  90. X      (while (> b 0)
  91. X    (setq c b
  92. X          b (% a b)
  93. X          a c))
  94. X      a))
  95. X   ((Math-looks-negp a) (math-gcd (math-neg a) b))
  96. X   ((Math-looks-negp b) (math-gcd a (math-neg b)))
  97. X   ((eq a 0) b)
  98. X   ((eq b 0) a)
  99. X   ((not (Math-integerp a))
  100. X    (if (Math-messy-integerp a)
  101. X    (math-gcd (math-trunc a) b)
  102. X      (calc-record-why 'integerp a)
  103. X      (list 'calcFunc-gcd a b)))
  104. X   ((not (Math-integerp b))
  105. X    (if (Math-messy-integerp b)
  106. X    (math-gcd a (math-trunc b))
  107. X      (calc-record-why 'integerp b)
  108. X      (list 'calcFunc-gcd a b)))
  109. X   (t
  110. X    (let (c)
  111. X      (if (Math-natnum-lessp a b)
  112. X      (setq c b b a a c))
  113. X      (while (and (consp a) (not (eq b 0)))
  114. X    (setq c b
  115. X          b (math-imod a b)
  116. X          a c))
  117. X      (while (> b 0)
  118. X    (setq c b
  119. X          b (% a b)
  120. X          a c))
  121. X      a)))
  122. X)
  123. X(fset 'calcFunc-gcd (symbol-function 'math-gcd))
  124. X
  125. X
  126. X
  127. X;;; General exponentiation.
  128. X
  129. X(defun math-pow (a b)   ; [O O N] [Public]
  130. X  (cond ((Math-zerop a)
  131. X     (if (math-zerop b)
  132. X         (math-reject-arg (list '^ a b) "Indeterminate form")
  133. X       (if (math-floatp b) (math-float a) a)))
  134. X    ((or (eq a 1) (eq b 1)) a)
  135. X    ((or (equal a '(float 1 0)) (equal b '(float 1 0))) a)
  136. X    ((Math-zerop b)
  137. X     (if (eq (car-safe a) 'mod)
  138. X         (math-make-mod 1 (nth 2 a))
  139. X       (if (or (math-floatp a) (math-floatp b))
  140. X           '(float 1 0) 1)))
  141. X    ((and (Math-integerp b) (math-numvecp a))
  142. X     (math-with-extra-prec 2
  143. X       (math-ipow a b)))
  144. X    (t
  145. X     (calc-extensions)
  146. X     (math-pow-fancy a b)))
  147. X)
  148. X(defun calcFunc-pow (a b)
  149. X  (math-normalize (list '^ a b))
  150. X)
  151. X
  152. X(defun math-ipow (a n)   ; [O O I] [Public]
  153. X  (cond ((Math-integer-negp n)
  154. X     (math-ipow (math-div 1 a) (Math-integer-neg n)))
  155. X    ((not (consp n))
  156. X     (if (and (Math-ratp a) (> n 20))
  157. X         (math-iipow-show a n)
  158. X       (math-iipow a n)))
  159. X    ((math-evenp n)
  160. X     (math-ipow (math-sqr a) (math-div2 n)))
  161. X    (t
  162. X     (math-mul a (math-ipow (math-sqr a)
  163. X                (math-div2 (math-add n -1))))))
  164. X)
  165. X
  166. X(defun math-iipow (a n)   ; [O O S]
  167. X  (cond ((= n 0) 1)
  168. X    ((= n 1) a)
  169. X    ((= (% n 2) 0) (math-iipow (math-sqr a) (/ n 2)))
  170. X    (t (math-mul a (math-iipow (math-sqr a) (/ n 2)))))
  171. X)
  172. X
  173. X(defun math-iipow-show (a n)   ; [O O S]
  174. X  (math-working "pow" a)
  175. X  (let ((val (cond
  176. X          ((= n 0) 1)
  177. X          ((= n 1) a)
  178. X          ((= (% n 2) 0) (math-iipow-show (math-sqr a) (/ n 2)))
  179. X          (t (math-mul a (math-iipow-show (math-sqr a) (/ n 2)))))))
  180. X    (math-working "pow" val)
  181. X    val)
  182. X)
  183. X
  184. X
  185. X
  186. X
  187. X
  188. X;;; Format the number A as a string.  [X N; X Z] [Public]
  189. X;;; Target line-width is W.
  190. X(defun math-format-stack-value (a &optional w)
  191. X  (or w (setq w (calc-window-width)))
  192. X  (let ((c (cond ((null a) "<nil>")
  193. X         ((eq calc-display-raw t) (format "%s" a))
  194. X         ((stringp a) a)
  195. X         ((eq a 'top-of-stack) ".")
  196. X         ((and (math-scalarp a)
  197. X               (memq calc-language '(nil flat unform)))
  198. X          (math-format-number a))
  199. X         (t (calc-extensions)
  200. X            (math-compose-expr a 0))))
  201. X    s ww)
  202. X    (if (and calc-display-just
  203. X         (< (setq ww (if (stringp c)
  204. X                 (length c)
  205. X               (math-comp-width c))) w))
  206. X    (setq c (math-comp-concat
  207. X         (make-string (if (eq calc-display-just 'center)
  208. X                  (/ (- w ww) 2)
  209. X                (- w ww)) 32)
  210. X         c))
  211. X      (if calc-line-numbering
  212. X      (setq c (math-comp-concat
  213. X           (if (eq calc-language 'big) "1:  " "    ") c))))
  214. X    (let ((s (if (stringp c)
  215. X         (if calc-display-raw
  216. X             (prin1-to-string c)
  217. X           c)
  218. X           (math-composition-to-string c w))))
  219. X      (if calc-language-output-filter
  220. X      (setq s (funcall calc-language-output-filter s)))
  221. X      (if (eq calc-language 'big)
  222. X      (concat s "\n")
  223. X    (if calc-line-numbering
  224. X        (progn
  225. X          (aset s 0 ?1)
  226. X          (aset s 1 ?:)))
  227. X    s)))
  228. X)
  229. X
  230. X(defun math-format-value (a &optional w)
  231. X  (if (and (math-scalarp a)
  232. X       (memq calc-language '(nil flat unform)))
  233. X      (math-format-number a)
  234. X    (calc-extensions)
  235. X    (math-composition-to-string (math-compose-expr a 0) w))
  236. X)
  237. X
  238. X(defun calc-window-width ()
  239. X  (1- (window-width (get-buffer-window (current-buffer))))
  240. X)
  241. X
  242. X(defun math-comp-concat (c1 c2)
  243. X  (if (and (stringp c1) (stringp c2))
  244. X      (concat c1 c2)
  245. X    (list 'horiz c1 c2))
  246. X)
  247. X
  248. X
  249. X
  250. X;;; Format an expression as a one-line string suitable for re-reading.
  251. X
  252. X(defun math-format-flat-expr (a prec)
  253. X  (cond
  254. X   ((or (not (or (consp a) (integerp a)))
  255. X    (eq calc-display-raw t))
  256. X    (let ((print-escape-newlines t))
  257. X      (concat "'" (prin1-to-string a))))
  258. X   ((math-scalarp a)
  259. X    (let ((calc-group-digits nil)
  260. X      (calc-point-char ".")
  261. X      (calc-frac-format (if (> (length calc-frac-format) 1) "::" ":"))
  262. X      (calc-complex-format nil)
  263. X      (calc-hms-format "%s@ %s' %s\"")
  264. X      (calc-language nil))
  265. X      (math-format-number a)))
  266. X   (t
  267. X    (calc-extensions)
  268. X    (math-format-flat-expr-fancy a prec)))
  269. X)
  270. X
  271. X
  272. X
  273. X;;; Format a number as a string.
  274. X(defun math-format-number (a)   ; [X N]   [Public]
  275. X  (cond
  276. X   ((eq calc-display-raw t) (format "%s" a))
  277. X   ((integerp a)
  278. X    (if (not (or calc-group-digits calc-leading-zeros))
  279. X    (if (= calc-number-radix 10)
  280. X        (int-to-string a)
  281. X      (if (< a 0)
  282. X          (concat "-" (math-format-number (- a)))
  283. X        (calc-extensions)
  284. X        (if math-radix-explicit-format
  285. X        (if calc-radix-formatter
  286. X            (funcall calc-radix-formatter
  287. X                 calc-number-radix
  288. X                 (if (= calc-number-radix 2)
  289. X                 (math-format-binary a)
  290. X                   (math-format-radix a)))
  291. X          (format "%d#%s" calc-number-radix
  292. X              (if (= calc-number-radix 2)
  293. X                  (math-format-binary a)
  294. X                (math-format-radix a))))
  295. X          (math-format-radix a))))
  296. X      (math-format-number (math-bignum a))))
  297. X   ((stringp a) a)
  298. X   ((eq (car a) 'bigpos) (math-format-bignum (cdr a)))
  299. X   ((eq (car a) 'bigneg) (concat "-" (math-format-bignum (cdr a))))
  300. X   ((eq (car a) 'frac)
  301. X    (if (> (length calc-frac-format) 1)
  302. X    (if (Math-integer-negp (nth 1 a))
  303. X        (concat "-" (math-format-number (math-neg a)))
  304. X      (let ((q (math-idivmod (nth 1 a) (nth 2 a))))
  305. X        (concat (math-format-number (car q))
  306. X            (substring calc-frac-format 0 1)
  307. X            (let ((math-radix-explicit-format nil))
  308. X              (math-format-number (cdr q)))
  309. X            (substring calc-frac-format 1 2)
  310. X            (let ((math-radix-explicit-format nil))
  311. X              (math-format-number (nth 2 a))))))
  312. X      (concat (math-format-number (nth 1 a))
  313. X          calc-frac-format
  314. X          (let ((math-radix-explicit-format nil))
  315. X        (math-format-number (nth 2 a))))))
  316. X   ((eq (car a) 'float)
  317. X    (if (Math-integer-negp (nth 1 a))
  318. X    (concat "-" (math-format-number (math-neg a)))
  319. X      (let ((mant (nth 1 a))
  320. X        (exp (nth 2 a))
  321. X        (fmt (car calc-float-format))
  322. X        (figs (nth 1 calc-float-format))
  323. X        (point calc-point-char)
  324. X        str)
  325. X    (if (and (eq fmt 'fix)
  326. X         (or (and (< figs 0) (setq figs (- figs)))
  327. X             (> (+ exp (math-numdigs mant)) (- figs))))
  328. X        (progn
  329. X          (setq mant (math-scale-rounding mant (+ exp figs))
  330. X            str (if (integerp mant)
  331. X                (int-to-string mant)
  332. X              (math-format-bignum-decimal (cdr mant))))
  333. X          (if (<= (length str) figs)
  334. X          (setq str (concat (make-string (1+ (- figs (length str))) ?0)
  335. X                    str)))
  336. X          (if (> figs 0)
  337. X          (setq str (concat (substring str 0 (- figs)) point
  338. X                    (substring str (- figs))))
  339. X        (setq str (concat str point)))
  340. X          (if calc-group-digits
  341. X          (setq str (math-group-float str))))
  342. X      (if (< figs 0)
  343. X          (setq figs (+ calc-internal-prec figs)))
  344. X      (if (> figs 0)
  345. X          (let ((adj (- figs (math-numdigs mant))))
  346. X        (if (< adj 0)
  347. X            (setq mant (math-scale-rounding mant adj)
  348. X              exp (- exp adj)))))
  349. X      (setq str (if (integerp mant)
  350. X            (int-to-string mant)
  351. X              (math-format-bignum-decimal (cdr mant))))
  352. X      (let* ((len (length str))
  353. X         (dpos (+ exp len)))
  354. X        (if (and (eq fmt 'float)
  355. X             (<= dpos (+ calc-internal-prec calc-display-sci-high))
  356. X             (>= dpos (+ calc-display-sci-low 2)))
  357. X        (progn
  358. X          (cond
  359. X           ((= dpos 0)
  360. X            (setq str (concat "0" point str)))
  361. X           ((and (<= exp 0) (> dpos 0))
  362. X            (setq str (concat (substring str 0 dpos) point
  363. X                      (substring str dpos))))
  364. X           ((> exp 0)
  365. X            (setq str (concat str (make-string exp ?0) point)))
  366. X           (t   ; (< dpos 0)
  367. X            (setq str (concat "0" point
  368. X                      (make-string (- dpos) ?0) str))))
  369. X          (if calc-group-digits
  370. X              (setq str (math-group-float str))))
  371. X          (let* ((eadj (+ exp len))
  372. X             (scale (if (eq fmt 'eng)
  373. X                (1+ (% (+ eadj 300002) 3))
  374. X                  1)))
  375. X        (if (> scale (length str))
  376. X            (setq str (concat str (make-string (- scale (length str))
  377. X                               ?0))))
  378. X        (if (< scale (length str))
  379. X            (setq str (concat (substring str 0 scale) point
  380. X                      (substring str scale))))
  381. X        (if calc-group-digits
  382. X            (setq str (math-group-float str)))
  383. X        (setq str (concat str
  384. X                  (if (eq calc-language 'math)
  385. X                      "*10.^" "e")
  386. X                  (int-to-string (- eadj scale))))))))
  387. X    str)))
  388. X   (t
  389. X    (calc-extensions)
  390. X    (math-format-number-fancy a)))
  391. X)
  392. X
  393. X(defvar math-radix-explicit-format t)
  394. X
  395. X(defun math-format-bignum (a)   ; [X L]
  396. X  (if (and (= calc-number-radix 10)
  397. X       (not calc-leading-zeros)
  398. X       (not calc-group-digits))
  399. X      (math-format-bignum-decimal a)
  400. X    (calc-extensions)
  401. X    (math-format-bignum-fancy a))
  402. X)
  403. X
  404. X(defun math-format-bignum-decimal (a)   ; [X L]
  405. X  (if a
  406. X      (let ((s ""))
  407. X    (while (cdr (cdr a))
  408. X      (setq s (concat (format "%06d" (+ (* (nth 1 a) 1000) (car a))) s)
  409. X        a (cdr (cdr a))))
  410. X    (concat (int-to-string (+ (* (or (nth 1 a) 0) 1000) (car a))) s))
  411. X    "0")
  412. X)
  413. X
  414. X
  415. X
  416. X;;; Parse a simple number in string form.   [N X] [Public]
  417. X(defun math-read-number (s)
  418. X  (math-normalize
  419. X   (cond
  420. X
  421. X    ;; Integers (most common case)
  422. X    ((string-match "\\` *\\([0-9]+\\) *\\'" s)
  423. X     (let ((digs (math-match-substring s 1)))
  424. X       (if (and (eq calc-language 'c)
  425. X        (> (length digs) 1)
  426. X        (eq (aref digs 0) ?0))
  427. X       (math-read-number (concat "8#" digs))
  428. X     (if (<= (length digs) 6)
  429. X         (string-to-int digs)
  430. X       (cons 'bigpos (math-read-bignum digs))))))
  431. X
  432. X    ;; Clean up the string if necessary
  433. X    ((string-match "\\`\\(.*\\)[ \t\n]+\\([^\001]\\)*\\'" s)
  434. X     (math-read-number (concat (math-match-substring s 1)
  435. X                   (math-match-substring s 2))))
  436. X
  437. X    ;; Minus sign
  438. X    ((string-match "^[-_]\\(.*\\)$" s)
  439. X     (let ((val (math-read-number (math-match-substring s 1))))
  440. X       (and val (math-neg val))))
  441. X
  442. X    ;; Plus sign
  443. X    ((string-match "^\\+\\(.*\\)$" s)
  444. X     (math-read-number (math-match-substring s 1)))
  445. X
  446. X    ;; Forms that require extensions module
  447. X    ((string-match "[a-df-zA-DF-Z/@'\"#^]" s)
  448. X     (calc-extensions)
  449. X     (math-read-number-fancy s))
  450. X
  451. X    ;; Integer+fractions
  452. X    ((string-match "^\\(.*\\)[:/]\\(.*\\)[:/]\\(.*\\)$" s)
  453. X     (let ((int (math-match-substring s 1))
  454. X       (num (math-match-substring s 2))
  455. X       (den (math-match-substring s 3)))
  456. X       (let ((int (if (> (length int) 0) (math-read-number int) 0))
  457. X         (num (if (> (length num) 0) (math-read-number num) 1))
  458. X         (den (if (> (length num) 0) (math-read-number den) 1)))
  459. X     (and int num den
  460. X          (math-integerp int) (math-integerp num) (math-integerp den)
  461. X          (not (math-zerop den))
  462. X          (list 'frac (math-add num (math-mul int den)) den)))))
  463. X
  464. X    ;; Fractions
  465. X    ((string-match "^\\(.*\\)[:/]\\(.*\\)$" s)
  466. X     (let ((num (math-match-substring s 1))
  467. X       (den (math-match-substring s 2)))
  468. X       (let ((num (if (> (length num) 0) (math-read-number num) 1))
  469. X         (den (if (> (length num) 0) (math-read-number den) 1)))
  470. X     (and num den (math-integerp num) (math-integerp den)
  471. X          (not (math-zerop den))
  472. X          (list 'frac num den)))))
  473. X
  474. X    ;; Decimal point
  475. X    ((string-match "^\\([0-9]*\\)\\.\\([0-9]*\\)$" s)
  476. X     (let ((int (math-match-substring s 1))
  477. X       (frac (math-match-substring s 2)))
  478. X       (let ((ilen (length int))
  479. X         (flen (length frac)))
  480. X     (let ((int (if (> ilen 0) (math-read-number int) 0))
  481. X           (frac (if (> flen 0) (math-read-number frac) 0)))
  482. X       (and int frac (or (> ilen 0) (> flen 0))
  483. X        (list 'float
  484. X              (math-add (math-scale-int int flen) frac)
  485. X              (- flen)))))))
  486. X
  487. X    ;; "e" notation
  488. X    ((string-match "^\\(.*\\)[eE]\\([-+]?[0-9]+\\)$" s)
  489. X     (let ((mant (math-match-substring s 1))
  490. X       (exp (math-match-substring s 2)))
  491. X       (let ((mant (if (> (length mant) 0) (math-read-number mant) 1))
  492. X         (exp (string-to-int exp)))
  493. X     (and mant (math-realp mant)
  494. X          (let ((mant (math-float mant)))
  495. X        (list 'float (nth 1 mant) (+ (nth 2 mant) exp)))))))
  496. X
  497. X    ;; Syntax error!
  498. X    (t nil)))
  499. X)
  500. X
  501. X(defun math-match-substring (s n)
  502. X  (if (match-beginning n)
  503. X      (substring s (match-beginning n) (match-end n))
  504. X    "")
  505. X)
  506. X
  507. X(defun math-read-bignum (s)   ; [l X]
  508. X  (if (> (length s) 3)
  509. X      (cons (string-to-int (substring s -3))
  510. X        (math-read-bignum (substring s 0 -3)))
  511. X    (list (string-to-int s)))
  512. X)
  513. X
  514. X(defun math-read-radix-digit (dig)   ; [D S; Z S]
  515. X  (if (> dig ?9)
  516. X      (if (< dig ?A)
  517. X      nil
  518. X    (- dig 55))
  519. X    (if (>= dig ?0)
  520. X    (- dig ?0)
  521. X      nil))
  522. X)
  523. X
  524. X
  525. X
  526. X;;; Algebraic expression parsing.   [Public]
  527. X
  528. X(defun math-read-exprs (exp-str)
  529. X  (let ((exp-pos 0)
  530. X    (exp-old-pos 0)
  531. X    (exp-keep-spaces nil)
  532. X    exp-token exp-data)
  533. X    (if calc-language-input-filter
  534. X    (setq exp-str (funcall calc-language-input-filter exp-str)))
  535. X    (while (setq exp-token (string-match "\\.\\." exp-str))
  536. X      (setq exp-str (concat (substring exp-str 0 exp-token) "\\dots"
  537. X                (substring exp-str (+ exp-token 2)))))
  538. X    (math-read-token)
  539. X    (let ((val (catch 'syntax (math-read-expr-list))))
  540. X      (if (stringp val)
  541. X      (list 'error exp-old-pos val)
  542. X    (if (equal exp-token 'end)
  543. X        val
  544. X      (list 'error exp-old-pos "Syntax error")))))
  545. X)
  546. X
  547. X(defun math-read-expr-list ()
  548. X  (let* ((exp-keep-spaces nil)
  549. X     (val (list (math-read-expr-level 0)))
  550. X     (last val))
  551. X    (while (equal exp-data ",")
  552. X      (math-read-token)
  553. X      (let ((rest (list (math-read-expr-level 0))))
  554. X    (setcdr last rest)
  555. X    (setq last rest)))
  556. X    val)
  557. X)
  558. X
  559. X(defun math-read-token ()
  560. X  (if (>= exp-pos (length exp-str))
  561. X      (setq exp-old-pos exp-pos
  562. X        exp-token 'end
  563. X        exp-data "\000")
  564. X    (let ((ch (elt exp-str exp-pos)))
  565. X      (setq exp-old-pos exp-pos)
  566. X      (cond ((memq ch '(32 10))
  567. X         (setq exp-pos (1+ exp-pos))
  568. X         (if exp-keep-spaces
  569. X         (setq exp-token 'space
  570. X               exp-data " ")
  571. X           (math-read-token)))
  572. X        ((or (and (>= ch ?a) (<= ch ?z))
  573. X         (and (>= ch ?A) (<= ch ?Z)))
  574. X         (string-match (if (eq calc-language 'tex)
  575. X                   "[a-zA-Z0-9']*"
  576. X                 "[a-zA-Z0-9'_]*")
  577. X               exp-str exp-pos)
  578. X         (setq exp-token 'symbol
  579. X           exp-pos (match-end 0)
  580. X           exp-data (math-restore-dashes
  581. X                 (math-match-substring exp-str 0))))
  582. X        ((or (and (>= ch ?0) (<= ch ?9))
  583. X         (memq ch '(?\. ?_)))
  584. X         (or (and (eq calc-language 'c)
  585. X              (string-match "0[xX][0-9a-fA-F]+" exp-str exp-pos))
  586. X         (string-match "_?\\([0-9]+.?0*@ *\\)?\\([0-9]+.?0*' *\\)?\\([0-9]+\\(#\\|\\^\\^\\)[0-9a-zA-Z:]+\\|[0-9]+:[0-9:]+\\|[0-9.]+\\([eE][-+_]?[0-9]+\\)?\"?\\)?" exp-str exp-pos))
  587. X         (setq exp-token 'number
  588. X           exp-data (math-match-substring exp-str 0)
  589. X           exp-pos (match-end 0)))
  590. X        ((eq ch ?\$)
  591. X         (string-match "\\$+" exp-str exp-pos)
  592. X         (setq exp-token 'dollar
  593. X           exp-data (- (match-end 0) (match-beginning 0))
  594. X           exp-pos (match-end 0)))
  595. X        ((eq (string-match "~=\\|<=\\|>=\\|<>\\|/=\\|\\+/-\\|\\\\dots\\|\\*\\*\\|<<\\|>>\\|==\\|!=\\|&&\\|||\\|!!"
  596. X                   exp-str exp-pos)
  597. X         exp-pos)
  598. X         (setq exp-token 'punc
  599. X           exp-data (math-match-substring exp-str 0)
  600. X           exp-pos (match-end 0)))
  601. X        ((and (eq ch ?\")
  602. X          (string-match "\\(\"\\([^\"\\]\\|\\\\.\\)*\\)\\(\"\\|\\'\\)" exp-str exp-pos))
  603. X         (setq exp-token 'string
  604. X           exp-data (math-match-substring exp-str 1)
  605. X           exp-pos (match-end 0)))
  606. X        ((and (= ch ?\\) (eq calc-language 'tex))
  607. X         (or (string-match "\\\\hbox *{\\([a-zA-Z0-9]+\\)}" exp-str exp-pos)
  608. X         (string-match "\\(\\\\\\([a-zA-Z]+\\|[^a-zA-Z]\\)\\)" exp-str exp-pos))
  609. X         (setq exp-token 'symbol
  610. X           exp-pos (match-end 0)
  611. X           exp-data (math-restore-dashes
  612. X                 (math-match-substring exp-str 1)))
  613. X         (if (or (equal exp-data "\\left")
  614. X             (equal exp-data "\\right"))
  615. X         (math-read-token)))
  616. X        (t
  617. X         (if (and (eq ch ?\{) (eq calc-language 'tex))
  618. X         (setq ch ?\())
  619. X         (if (and (eq ch ?\}) (eq calc-language 'tex))
  620. X         (setq ch ?\)))
  621. X         (setq exp-token 'punc
  622. X           exp-data (char-to-string ch)
  623. X           exp-pos (1+ exp-pos))))))
  624. X)
  625. X
  626. X(defconst math-standard-opers
  627. X  '( ( "u+"    ident         -1 1000 )
  628. X     ( "u-"    neg         -1 1000 )
  629. X     ( "u!"    calcFunc-lnot -1 1000 )
  630. X     ( "mod"   mod         400 400 )
  631. X     ( "+/-"   sdev         300 300 )
  632. X     ( "!"     calcFunc-fact 210  -1 )
  633. X     ( "^"     ^             201 200 )
  634. X     ( "*"     *             196 195 )
  635. X     ( "2x"    *             196 195 )
  636. X     ( "/"     /             190 191 )
  637. X     ( "%"     %             190 191 )
  638. X     ( "\\"    calcFunc-idiv 190 191 )
  639. X     ( "+"     +         180 181 )
  640. X     ( "-"     -         180 181 )
  641. X     ( "|"     |         170 171 )
  642. X     ( "<"     calcFunc-lt   160 161 )
  643. X     ( ">"     calcFunc-gt   160 161 )
  644. X     ( "<="    calcFunc-leq  160 161 )
  645. X     ( ">="    calcFunc-geq  160 161 )
  646. X     ( "="     calcFunc-eq   160 161 )
  647. X     ( "=="    calcFunc-eq   160 161 )
  648. X     ( "!="    calcFunc-neq  160 161 )
  649. X     ( "&&"    calcFunc-land 110 111 )
  650. X     ( "||"    calcFunc-lor  100 101 )
  651. X     ( "?"     calcFunc-if    91  90 )
  652. X))
  653. X(setq math-expr-opers math-standard-opers)
  654. X(setq math-expr-function-mapping nil)
  655. X(setq math-expr-variable-mapping nil)
  656. X
  657. X(defun math-read-expr-level (exp-prec)
  658. X  (let* ((x (math-read-factor)) op)
  659. X    (while (and (or (and (setq op (assoc exp-data math-expr-opers))
  660. X             (/= (nth 2 op) -1))
  661. X            (and (or (eq (nth 2 op) -1)
  662. X                 (memq exp-token '(symbol number dollar))
  663. X                 (equal exp-data "(")
  664. X                 (and (equal exp-data "[")
  665. X                  (not (eq calc-language 'math))
  666. X                  (not (and exp-keep-spaces
  667. X                        (eq (car-safe x) 'vec)))))
  668. X             (setq op (assoc "2x" math-expr-opers))))
  669. X        (>= (nth 2 op) exp-prec))
  670. X      (if (not (equal (car op) "2x"))
  671. X      (math-read-token))
  672. X      (and (memq (nth 1 op) '(sdev mod))
  673. X       (calc-extensions))
  674. X      (setq x (cond ((eq (nth 3 op) -1)
  675. X             (if (eq (nth 1 op) 'ident)
  676. X             x
  677. X               (list (nth 1 op) x)))
  678. X            ((equal (car op) "?")
  679. X             (let ((y (math-read-expr-level 0)))
  680. X               (or (equal exp-data ":")
  681. X               (throw 'syntax "Expected ':'"))
  682. X               (math-read-token)
  683. X               (list (nth 1 op)
  684. X                 x
  685. X                 y
  686. X                 (math-read-expr-level (nth 3 op)))))
  687. X            (t (list (nth 1 op)
  688. X                 x
  689. X                 (math-read-expr-level (nth 3 op)))))))
  690. X    x)
  691. X)
  692. X
  693. X(defun math-remove-dashes (x)
  694. X  (if (string-match "\\`\\(.*\\)-\\(.*\\)\\'" x)
  695. X      (math-remove-dashes
  696. X       (concat (math-match-substring x 1) "_" (math-match-substring x 2)))
  697. X    x)
  698. X)
  699. X
  700. X(defun math-restore-dashes (x)
  701. X  (if (string-match "\\`\\(.*\\)_\\(.*\\)\\'" x)
  702. X      (math-restore-dashes
  703. X       (concat (math-match-substring x 1) "-" (math-match-substring x 2)))
  704. X    x)
  705. X)
  706. X
  707. X(defun math-read-factor ()
  708. X  (let (op)
  709. X    (cond ((eq exp-token 'number)
  710. X       (let ((num (math-read-number exp-data)))
  711. X         (if (not num)
  712. X         (progn
  713. X           (setq exp-old-pos exp-pos)
  714. X           (throw 'syntax "Bad format")))
  715. X         (math-read-token)
  716. X         (if (and math-read-expr-quotes
  717. X              (consp num))
  718. X         (list 'quote num)
  719. X           num)))
  720. X      ((or (equal exp-data "-")
  721. X           (equal exp-data "+")
  722. X           (equal exp-data "!")
  723. X           (equal exp-data "|"))
  724. X       (setq exp-data (concat "u" exp-data))
  725. X       (math-read-factor))
  726. X      ((and (setq op (assoc exp-data math-expr-opers))
  727. X        (eq (nth 2 op) -1))
  728. X       (math-read-token)
  729. X       (let ((val (math-read-expr-level (nth 3 op))))
  730. X         (cond ((eq (nth 1 op) 'ident)
  731. X            val)
  732. X           ((and (math-numberp val)
  733. X             (equal (car op) "u-"))
  734. X            (math-neg val))
  735. X           (t (list (nth 1 op) val)))))
  736. X      ((eq exp-token 'symbol)
  737. X       (let ((sym (intern exp-data)))
  738. X         (math-read-token)
  739. X         (if (equal exp-data calc-function-open)
  740. X         (progn
  741. X           (math-read-token)
  742. X           (let ((args (if (equal exp-data calc-function-close)
  743. X                   nil
  744. X                 (math-read-expr-list))))
  745. X             (if (not (or (equal exp-data calc-function-close)
  746. X                  (eq exp-token 'end)))
  747. X             (throw 'syntax "Expected `)'"))
  748. X             (math-read-token)
  749. X             (let ((f (assq sym math-expr-function-mapping)))
  750. X               (if f
  751. X               (setq sym (cdr f))
  752. X             (or (string-match "-" (symbol-name sym))
  753. X                 (setq sym (intern (concat "calcFunc-"
  754. X                               (symbol-name sym)))))))
  755. X             (cons sym args)))
  756. X           (if math-read-expr-quotes
  757. X           sym
  758. X         (let ((val (list 'var
  759. X                  (intern (math-remove-dashes
  760. X                       (symbol-name sym)))
  761. X                  (if (string-match "-" (symbol-name sym))
  762. X                      sym
  763. X                    (intern (concat "var-"
  764. X                            (symbol-name sym)))))))
  765. X           (let ((v (assq (nth 1 val) math-expr-variable-mapping)))
  766. X             (and v (setq val (list 'var
  767. X                        (intern
  768. X                         (substring (symbol-name (cdr v)) 4))
  769. X                        (cdr v)))))
  770. X           (while (and (memq calc-language '(c pascal))
  771. X                   (equal exp-data "["))
  772. X             (math-read-token)
  773. X             (setq val (append (list 'calcFunc-subscr val)
  774. X                       (math-read-expr-list)))
  775. X             (if (equal exp-data "]")
  776. X             (math-read-token)
  777. X               (throw 'syntax "Expected ']'")))
  778. X           val)))))
  779. X      ((eq exp-token 'dollar)
  780. X       (if (>= (length calc-dollar-values) exp-data)
  781. X           (let ((num exp-data))
  782. X         (math-read-token)
  783. X         (setq calc-dollar-used (max calc-dollar-used num))
  784. X         (math-check-complete (nth (1- num) calc-dollar-values)))
  785. X         (throw 'syntax (if calc-dollar-values
  786. X                "Too many $'s"
  787. X                  "$'s not allowed in this context"))))
  788. X      ((equal exp-data "(")
  789. X       (let* ((exp (let ((exp-keep-spaces nil))
  790. X             (math-read-token)
  791. X             (math-read-expr-level 0))))
  792. X         (let ((exp-keep-spaces nil))
  793. X           (cond
  794. X        ((equal exp-data ",")
  795. X         (progn
  796. X           (math-read-token)
  797. X           (let ((exp2 (math-read-expr-level 0)))
  798. X             (setq exp
  799. X               (if (and exp2 (math-realp exp) (math-realp exp2))
  800. X                   (math-normalize (list 'cplx exp exp2))
  801. X                 (list '+ exp (list '* exp2 '(var i var-i))))))))
  802. X        ((equal exp-data ";")
  803. X         (progn
  804. X           (math-read-token)
  805. X           (let ((exp2 (math-read-expr-level 0)))
  806. X             (setq exp (if (and exp2 (math-realp exp)
  807. X                    (math-anglep exp2))
  808. X                   (math-normalize (list 'polar exp exp2))
  809. X                 (list '* exp
  810. X                       (list 'calcFunc-exp
  811. X                         (list '* exp2
  812. X                           '(var i var-i)))))))))
  813. X        ((equal exp-data "\\dots")
  814. X         (progn
  815. X           (math-read-token)
  816. X           (let ((exp2 (math-read-expr-level 0)))
  817. X             (setq exp
  818. X               (list 'intv
  819. X                 (if (equal exp-data ")") 0 1)
  820. X                 exp
  821. X                 exp2)))))))
  822. X         (if (not (or (equal exp-data ")")
  823. X              (and (equal exp-data "]") (eq (car-safe exp) 'intv))
  824. X              (eq exp-token 'end)))
  825. X         (throw 'syntax "Expected `)'"))
  826. X         (math-read-token)
  827. X         exp))
  828. X      ((eq exp-token 'string)
  829. X       (calc-extensions)
  830. X       (math-read-string))
  831. X      ((equal exp-data "[")
  832. X       (calc-extensions)
  833. X       (math-read-brackets t "]"))
  834. X      ((equal exp-data "{")
  835. X       (calc-extensions)
  836. X       (math-read-brackets nil "}"))
  837. X      (t (throw 'syntax "Expected a number"))))
  838. X)
  839. X
  840. X(defvar math-read-expr-quotes nil)
  841. X
  842. X
  843. X
  844. X
  845. X;;; Bug reporting
  846. X
  847. X(defun report-calc-bug (topic)
  848. X  "Report a bug in Calc, the GNU Emacs calculator.
  849. XPrompts for bug subject.  Leaves you in a mail buffer."
  850. X  (interactive "sBug Subject: ")
  851. X  (mail nil calc-bug-address topic)
  852. X  (goto-char (point-max))
  853. X  (insert "\nIn Calc 1.01, Emacs " (emacs-version) "\n\n")
  854. X  (message (substitute-command-keys "Type \\[mail-send] to send bug report."))
  855. X)
  856. X
  857. X
  858. X
  859. X;;; User-programmability.
  860. X
  861. X(defmacro defmath (func args &rest body)   ;  [Public]
  862. X  (calc-extensions)
  863. X  (math-do-defmath func args body)
  864. X)
  865. X
  866. X
  867. X
  868. X(if calc-always-load-extensions
  869. X    (calc-extensions)
  870. X)
  871. X
  872. X
  873. X
  874. X;;; End.
  875. X
  876. SHAR_EOF
  877. echo "File calc.el is complete"
  878. chmod 0664 calc.el || echo "restore of calc.el fails"
  879. set `wc -c calc.el`;Sum=$1
  880. if test "$Sum" != "124988"
  881. then echo original size 124988, current size $Sum;fi
  882. echo "x - extracting calc-ext.el (Text)"
  883. sed 's/^X//' << 'SHAR_EOF' > calc-ext.el &&
  884. X;; Calculator for GNU Emacs, part II
  885. X;; Copyright (C) 1990 Dave Gillespie
  886. X
  887. X;; This file is part of GNU Emacs.
  888. X
  889. X;; GNU Emacs is distributed in the hope that it will be useful,
  890. X;; but WITHOUT ANY WARRANTY.  No author or distributor
  891. X;; accepts responsibility to anyone for the consequences of using it
  892. X;; or for whether it serves any particular purpose or works at all,
  893. X;; unless he says so in writing.  Refer to the GNU Emacs General Public
  894. X;; License for full details.
  895. X
  896. X;; Everyone is granted permission to copy, modify and redistribute
  897. X;; GNU Emacs, but only under the conditions described in the
  898. X;; GNU Emacs General Public License.   A copy of this license is
  899. X;; supposed to have been given to you along with GNU Emacs so you
  900. X;; can know your rights and responsibilities.  It should be in a
  901. X;; file named COPYING.  Among other things, the copyright notice
  902. X;; and this notice must be preserved on all copies.
  903. X
  904. X
  905. X
  906. X(provide 'calc-ext)
  907. X
  908. X(setq calc-extensions-loaded t)
  909. X
  910. X;;; This function is the autoload "hook" to cause this file to be loaded.
  911. X(defun calc-extensions ()
  912. X  t
  913. X)
  914. X
  915. X;;; Auto-load part I, in case this part was loaded first.
  916. X(if (fboundp 'calc)
  917. X    (and (eq (car-safe (symbol-function 'calc)) 'autoload)
  918. X     (load (nth 1 (symbol-function 'calc))))
  919. X  (error "Main part of Calc must be present in order to load this file."))
  920. X
  921. X;;; If the following fails with "Cannot open load file: calc"
  922. X;;; do "M-x load-file calc.elc" before compiling calc-ext.el.
  923. X(require 'calc)  ;;; This should only occur in the byte compiler.
  924. X
  925. X
  926. X
  927. X(progn
  928. X  (define-key calc-mode-map ":" 'calc-fdiv)
  929. X  (define-key calc-mode-map "\\" 'calc-idiv)
  930. X  (define-key calc-mode-map "|" 'calc-concat)
  931. X  (define-key calc-mode-map "!" 'calc-factorial)
  932. X  (define-key calc-mode-map "A" 'calc-abs)
  933. X  (define-key calc-mode-map "B" 'calc-log)
  934. X  (define-key calc-mode-map "C" 'calc-cos)
  935. X  (define-key calc-mode-map "D" 'calc-redo)
  936. X  (define-key calc-mode-map "E" 'calc-exp)
  937. X  (define-key calc-mode-map "F" 'calc-floor)
  938. X  (define-key calc-mode-map "G" 'calc-argument)
  939. X  (define-key calc-mode-map "H" 'calc-hyperbolic)
  940. X  (define-key calc-mode-map "I" 'calc-inverse)
  941. X  (define-key calc-mode-map "J" 'calc-conj)
  942. X  (define-key calc-mode-map "K" 'calc-call-last-kbd-macro)
  943. X  (define-key calc-mode-map "L" 'calc-ln)
  944. X  (define-key calc-mode-map "M" 'calc-more-recursion-depth)
  945. X  (define-key calc-mode-map "N" 'calc-eval-num)
  946. X  (define-key calc-mode-map "P" 'calc-pi)
  947. X  (define-key calc-mode-map "Q" 'calc-sqrt)
  948. X  (define-key calc-mode-map "R" 'calc-round)
  949. X  (define-key calc-mode-map "S" 'calc-sin)
  950. X  (define-key calc-mode-map "T" 'calc-tan)
  951. X  (define-key calc-mode-map "U" 'calc-undo)
  952. X  (define-key calc-mode-map "X" 'calc-last-x)
  953. X  (define-key calc-mode-map "l" 'calc-let)
  954. X  (define-key calc-mode-map "r" 'calc-recall)
  955. X  (define-key calc-mode-map "s" 'calc-store)
  956. X  (define-key calc-mode-map "x" 'calc-execute-extended-command)
  957. X
  958. X  (define-key calc-mode-map "(" 'calc-begin-complex)
  959. X  (define-key calc-mode-map ")" 'calc-end-complex)
  960. X  (define-key calc-mode-map "[" 'calc-begin-vector)
  961. X  (define-key calc-mode-map "]" 'calc-end-vector)
  962. X  (define-key calc-mode-map "," 'calc-comma)
  963. X  (define-key calc-mode-map ";" 'calc-semi)
  964. X  (define-key calc-mode-map "`" 'calc-edit)
  965. X  (define-key calc-mode-map "=" 'calc-evaluate)
  966. X  (define-key calc-mode-map "~" 'calc-num-prefix)
  967. X  (define-key calc-mode-map "y" 'calc-copy-to-buffer)
  968. X  (define-key calc-mode-map "\C-k" 'calc-kill)
  969. X  (define-key calc-mode-map "\M-k" 'calc-copy-as-kill)
  970. X  (define-key calc-mode-map "\C-w" 'calc-kill-region)
  971. X  (define-key calc-mode-map "\M-w" 'calc-copy-region-as-kill)
  972. X  (define-key calc-mode-map "\C-y" 'calc-yank)
  973. X  (define-key calc-mode-map "\C-_" 'calc-undo)
  974. X
  975. X  (define-key calc-mode-map "a" nil)
  976. X  (define-key calc-mode-map "a?" 'calc-a-prefix-help)
  977. X  (define-key calc-mode-map "ab" 'calc-substitute)
  978. X  (define-key calc-mode-map "ac" 'calc-collect)
  979. X  (define-key calc-mode-map "ad" 'calc-derivative)
  980. X  (define-key calc-mode-map "ae" 'calc-simplify-extended)
  981. X  (define-key calc-mode-map "ai" 'calc-integral)
  982. X  (define-key calc-mode-map "ar" 'calc-rewrite)
  983. X  (define-key calc-mode-map "as" 'calc-simplify)
  984. X  (define-key calc-mode-map "at" 'calc-taylor)
  985. X  (define-key calc-mode-map "ax" 'calc-expand)
  986. X  (define-key calc-mode-map "aI" 'calc-integral-limit)
  987. X  (define-key calc-mode-map "aS" 'calc-solve-for)
  988. X  (define-key calc-mode-map "a=" 'calc-equal-to)
  989. X  (define-key calc-mode-map "a#" 'calc-not-equal-to)
  990. X  (define-key calc-mode-map "a<" 'calc-less-than)
  991. X  (define-key calc-mode-map "a>" 'calc-greater-than)
  992. X  (define-key calc-mode-map "a[" 'calc-less-equal)
  993. X  (define-key calc-mode-map "a]" 'calc-greater-equal)
  994. X  (define-key calc-mode-map "a{" 'calc-in-set)
  995. X  (define-key calc-mode-map "a&" 'calc-logical-and)
  996. X  (define-key calc-mode-map "a|" 'calc-logical-or)
  997. X  (define-key calc-mode-map "a!" 'calc-logical-not)
  998. X
  999. X  (define-key calc-mode-map "b" nil)
  1000. X  (define-key calc-mode-map "b?" 'calc-b-prefix-help)
  1001. X  (define-key calc-mode-map "ba" 'calc-and)
  1002. X  (define-key calc-mode-map "bc" 'calc-clip)
  1003. X  (define-key calc-mode-map "bd" 'calc-diff)
  1004. X  (define-key calc-mode-map "bl" 'calc-lshift-binary)
  1005. X  (define-key calc-mode-map "bn" 'calc-not)
  1006. X  (define-key calc-mode-map "bo" 'calc-or)
  1007. X  (define-key calc-mode-map "br" 'calc-rshift-binary)
  1008. X  (define-key calc-mode-map "bR" 'calc-rotate-binary)
  1009. X  (define-key calc-mode-map "bs" 'calc-shift-binary)
  1010. X  (define-key calc-mode-map "bw" 'calc-word-size)
  1011. X  (define-key calc-mode-map "bx" 'calc-xor)
  1012. X
  1013. X  (define-key calc-mode-map "c" nil)
  1014. X  (define-key calc-mode-map "c?" 'calc-c-prefix-help)
  1015. X  (define-key calc-mode-map "c1" 'calc-clean-1)
  1016. X  (define-key calc-mode-map "c2" 'calc-clean-2)
  1017. X  (define-key calc-mode-map "c3" 'calc-clean-3)
  1018. X  (define-key calc-mode-map "cc" 'calc-clean)
  1019. X  (define-key calc-mode-map "cd" 'calc-to-degrees)
  1020. X  (define-key calc-mode-map "cf" 'calc-float)
  1021. X  (define-key calc-mode-map "ch" 'calc-to-hms)
  1022. X  (define-key calc-mode-map "cp" 'calc-polar)
  1023. X  (define-key calc-mode-map "cr" 'calc-to-radians)
  1024. X  (define-key calc-mode-map "cF" 'calc-fraction)
  1025. X
  1026. X  (define-key calc-mode-map "d" nil)
  1027. X  (define-key calc-mode-map "d?" 'calc-d-prefix-help)
  1028. X  (define-key calc-mode-map "d0" 'calc-decimal-radix)
  1029. X  (define-key calc-mode-map "d2" 'calc-binary-radix)
  1030. X  (define-key calc-mode-map "d6" 'calc-hex-radix)
  1031. X  (define-key calc-mode-map "d8" 'calc-octal-radix)
  1032. X  (define-key calc-mode-map "db" 'calc-line-breaking)
  1033. X  (define-key calc-mode-map "dc" 'calc-complex-notation)
  1034. X  (define-key calc-mode-map "de" 'calc-eng-notation)
  1035. X  (define-key calc-mode-map "df" 'calc-fix-notation)
  1036. X  (define-key calc-mode-map "dg" 'calc-group-digits)
  1037. X  (define-key calc-mode-map "dh" 'calc-hms-notation)
  1038. X  (define-key calc-mode-map "di" 'calc-i-notation)
  1039. X  (define-key calc-mode-map "dj" 'calc-j-notation)
  1040. X  (define-key calc-mode-map "dl" 'calc-line-numbering)
  1041. X  (define-key calc-mode-map "dn" 'calc-normal-notation)
  1042. X  (define-key calc-mode-map "do" 'calc-over-notation)
  1043. X  (define-key calc-mode-map "dr" 'calc-radix)
  1044. X  (define-key calc-mode-map "ds" 'calc-sci-notation)
  1045. X  (define-key calc-mode-map "dt" 'calc-truncate-stack)
  1046. X  (define-key calc-mode-map "dw" 'calc-auto-why)
  1047. X  (define-key calc-mode-map "dz" 'calc-leading-zeros)
  1048. X  (define-key calc-mode-map "dB" 'calc-big-language)
  1049. X  (define-key calc-mode-map "dC" 'calc-c-language)
  1050. X  (define-key calc-mode-map "dF" 'calc-fortran-language)
  1051. X  (define-key calc-mode-map "dM" 'calc-mathematica-language)
  1052. X  (define-key calc-mode-map "dN" 'calc-normal-language)
  1053. X  (define-key calc-mode-map "dO" 'calc-flat-language)
  1054. X  (define-key calc-mode-map "dP" 'calc-pascal-language)
  1055. X  (define-key calc-mode-map "dT" 'calc-tex-language)
  1056. X  (define-key calc-mode-map "dU" 'calc-unformatted-language)
  1057. X  (define-key calc-mode-map "d[" 'calc-truncate-up)
  1058. X  (define-key calc-mode-map "d]" 'calc-truncate-down)
  1059. X  (define-key calc-mode-map "d." 'calc-point-char)
  1060. X  (define-key calc-mode-map "d," 'calc-group-char)
  1061. X  (define-key calc-mode-map "d\"" 'calc-display-strings)
  1062. X  (define-key calc-mode-map "d<" 'calc-left-justify)
  1063. X  (define-key calc-mode-map "d=" 'calc-center-justify)
  1064. X  (define-key calc-mode-map "d>" 'calc-right-justify)
  1065. X  (define-key calc-mode-map "d'" 'calc-display-raw)
  1066. X  (define-key calc-mode-map "d`" 'calc-realign)
  1067. X  (define-key calc-mode-map "d~" 'calc-refresh)
  1068. X
  1069. X  (define-key calc-mode-map "k" nil)
  1070. X  (define-key calc-mode-map "k?" 'calc-k-prefix-help)
  1071. X  (define-key calc-mode-map "ka" 'calc-random-again)
  1072. X  (define-key calc-mode-map "kb" 'calc-choose)
  1073. X  (define-key calc-mode-map "kd" 'calc-double-factorial)
  1074. X  (define-key calc-mode-map "kf" 'calc-prime-factors)
  1075. X  (define-key calc-mode-map "kg" 'calc-gcd)
  1076. X  (define-key calc-mode-map "kl" 'calc-lcm)
  1077. X  (define-key calc-mode-map "km" 'calc-moebius)
  1078. X  (define-key calc-mode-map "kn" 'calc-next-prime)
  1079. X  (define-key calc-mode-map "kp" 'calc-prime-test)
  1080. X  (define-key calc-mode-map "kr" 'calc-random)
  1081. X  (define-key calc-mode-map "kt" 'calc-totient)
  1082. X  (define-key calc-mode-map "kG" 'calc-extended-gcd)
  1083. X
  1084. X  (define-key calc-mode-map "m" nil)
  1085. X  (define-key calc-mode-map "m?" 'calc-m-prefix-help)
  1086. X  (define-key calc-mode-map "ma" 'calc-algebraic-mode)
  1087. X  (define-key calc-mode-map "md" 'calc-degrees-mode)
  1088. X  (define-key calc-mode-map "mf" 'calc-frac-mode)
  1089. X  (define-key calc-mode-map "mh" 'calc-hms-mode)
  1090. X  (define-key calc-mode-map "mm" 'calc-save-modes)
  1091. X  (define-key calc-mode-map "mp" 'calc-polar-mode)
  1092. X  (define-key calc-mode-map "mr" 'calc-radians-mode)
  1093. X  (define-key calc-mode-map "ms" 'calc-symbolic-mode)
  1094. X  (define-key calc-mode-map "mw" 'calc-working)
  1095. X  (define-key calc-mode-map "mx" 'calc-always-load-extensions)
  1096. X  (define-key calc-mode-map "mA" 'calc-alg-simplify-mode)
  1097. X  (define-key calc-mode-map "mB" 'calc-bin-simplify-mode)
  1098. X  (define-key calc-mode-map "mD" 'calc-default-simplify-mode)
  1099. X  (define-key calc-mode-map "mE" 'calc-ext-simplify-mode)
  1100. X  (define-key calc-mode-map "mN" 'calc-num-simplify-mode)
  1101. X  (define-key calc-mode-map "mO" 'calc-no-simplify-mode)
  1102. X  (define-key calc-mode-map "mU" 'calc-units-simplify-mode)
  1103. X
  1104. X  (define-key calc-mode-map "t" nil)
  1105. X  (define-key calc-mode-map "t?" 'calc-t-prefix-help)
  1106. X  (define-key calc-mode-map "tb" 'calc-trail-backward)
  1107. X  (define-key calc-mode-map "td" 'calc-trail-display)
  1108. X  (define-key calc-mode-map "tf" 'calc-trail-forward)
  1109. X  (define-key calc-mode-map "th" 'calc-trail-here)
  1110. X  (define-key calc-mode-map "ti" 'calc-trail-in)
  1111. X  (define-key calc-mode-map "tk" 'calc-trail-kill)
  1112. X  (define-key calc-mode-map "tm" 'calc-trail-marker)
  1113. X  (define-key calc-mode-map "tn" 'calc-trail-next)
  1114. X  (define-key calc-mode-map "to" 'calc-trail-out)
  1115. X  (define-key calc-mode-map "tp" 'calc-trail-previous)
  1116. X  (define-key calc-mode-map "tr" 'calc-trail-isearch-backward)
  1117. X  (define-key calc-mode-map "ts" 'calc-trail-isearch-forward)
  1118. X  (define-key calc-mode-map "ty" 'calc-trail-yank)
  1119. X  (define-key calc-mode-map "t[" 'calc-trail-first)
  1120. X  (define-key calc-mode-map "t]" 'calc-trail-last)
  1121. X  (define-key calc-mode-map "t<" 'calc-trail-scroll-left)
  1122. X  (define-key calc-mode-map "t>" 'calc-trail-scroll-right)
  1123. X
  1124. X  (define-key calc-mode-map "u" 'nil)
  1125. X  (define-key calc-mode-map "u?" 'calc-u-prefix-help)
  1126. X  (define-key calc-mode-map "ub" 'calc-base-units)
  1127. X  (define-key calc-mode-map "uc" 'calc-convert-units)
  1128. X  (define-key calc-mode-map "ud" 'calc-define-unit)
  1129. X  (define-key calc-mode-map "ue" 'calc-explain-units)
  1130. X  (define-key calc-mode-map "ug" 'calc-get-unit-definition)
  1131. X  (define-key calc-mode-map "up" 'calc-permanent-units)
  1132. X  (define-key calc-mode-map "ur" 'calc-remove-units)
  1133. X  (define-key calc-mode-map "us" 'calc-simplify-units)
  1134. X  (define-key calc-mode-map "ut" 'calc-convert-temperature)
  1135. X  (define-key calc-mode-map "uu" 'calc-undefine-unit)
  1136. X  (define-key calc-mode-map "uv" 'calc-enter-units-table)
  1137. X  (define-key calc-mode-map "ux" 'calc-extract-units)
  1138. X  (define-key calc-mode-map "uV" 'calc-view-units-table)
  1139. X
  1140. X  (define-key calc-mode-map "v" 'nil)
  1141. X  (define-key calc-mode-map "v?" 'calc-v-prefix-help)
  1142. X  (define-key calc-mode-map "va" 'calc-arrange-vector)
  1143. X  (define-key calc-mode-map "vb" 'calc-build-vector)
  1144. X  (define-key calc-mode-map "vc" 'calc-mcol)
  1145. X  (define-key calc-mode-map "vd" 'calc-diag)
  1146. X  (define-key calc-mode-map "vh" 'calc-histogram)
  1147. X  (define-key calc-mode-map "vi" 'calc-ident)
  1148. X  (define-key calc-mode-map "vl" 'calc-vlength)
  1149. X  (define-key calc-mode-map "vn" 'calc-rnorm)
  1150. X  (define-key calc-mode-map "vp" 'calc-pack)
  1151. X  (define-key calc-mode-map "vr" 'calc-mrow)
  1152. X  (define-key calc-mode-map "vs" 'calc-sort)
  1153. X  (define-key calc-mode-map "vt" 'calc-transpose)
  1154. X  (define-key calc-mode-map "vu" 'calc-unpack)
  1155. X  (define-key calc-mode-map "vx" 'calc-index)
  1156. X  (define-key calc-mode-map "vA" 'calc-apply)
  1157. X  (define-key calc-mode-map "vC" 'calc-cross)
  1158. X  (define-key calc-mode-map "vD" 'calc-mdet)
  1159. X  (define-key calc-mode-map "vI" 'calc-inv)
  1160. X  (define-key calc-mode-map "vJ" 'calc-conj-transpose)
  1161. X  (define-key calc-mode-map "vL" 'calc-mlud)
  1162. X  (define-key calc-mode-map "vM" 'calc-map)
  1163. X  (define-key calc-mode-map "vN" 'calc-cnorm)
  1164. X  (define-key calc-mode-map "vR" 'calc-reduce)
  1165. X  (define-key calc-mode-map "vT" 'calc-mtrace)
  1166. X  (define-key calc-mode-map "v<" 'calc-matrix-left-justify)
  1167. X  (define-key calc-mode-map "v=" 'calc-matrix-center-justify)
  1168. X  (define-key calc-mode-map "v>" 'calc-matrix-right-justify)
  1169. X  (define-key calc-mode-map "v," 'calc-vector-commas)
  1170. X  (define-key calc-mode-map "v[" 'calc-vector-brackets)
  1171. X  (define-key calc-mode-map "v{" 'calc-vector-braces)
  1172. X  (define-key calc-mode-map "v(" 'calc-vector-parens)
  1173. X  (aset calc-mode-map ?V (aref calc-mode-map ?v))
  1174. X
  1175. X  (define-key calc-mode-map "z" 'nil)
  1176. X  (define-key calc-mode-map "z?" 'calc-z-prefix-help)
  1177. X
  1178. X  (define-key calc-mode-map "Z" 'nil)
  1179. X  (define-key calc-mode-map "Z?" 'calc-shift-Z-prefix-help)
  1180. X  (define-key calc-mode-map "Zd" 'calc-user-define)
  1181. X  (define-key calc-mode-map "Ze" 'calc-user-define-edit)
  1182. X  (define-key calc-mode-map "Zf" 'calc-user-define-formula)
  1183. X  (define-key calc-mode-map "Zg" 'calc-get-user-defn)
  1184. X  (define-key calc-mode-map "Zk" 'calc-user-define-kbd-macro)
  1185. X  (define-key calc-mode-map "Zp" 'calc-user-define-permanent)
  1186. X  (define-key calc-mode-map "Zu" 'calc-user-undefine)
  1187. X  (define-key calc-mode-map "Zv" 'calc-permanent-variable)
  1188. X  (define-key calc-mode-map "Z[" 'calc-kbd-if)
  1189. X  (define-key calc-mode-map "Z:" 'calc-kbd-else)
  1190. X  (define-key calc-mode-map "Z|" 'calc-kbd-else-if)
  1191. X  (define-key calc-mode-map "Z]" 'calc-kbd-end-if)
  1192. X  (define-key calc-mode-map "Z<" 'calc-kbd-repeat)
  1193. X  (define-key calc-mode-map "Z>" 'calc-kbd-end-repeat)
  1194. X  (define-key calc-mode-map "Z(" 'calc-kbd-for)
  1195. X  (define-key calc-mode-map "Z)" 'calc-kbd-end-for)
  1196. X  (define-key calc-mode-map "Z{" 'calc-kbd-loop)
  1197. X  (define-key calc-mode-map "Z}" 'calc-kbd-end-loop)
  1198. X  (define-key calc-mode-map "Z/" 'calc-kbd-break)
  1199. X  (define-key calc-mode-map "Z`" 'calc-kbd-push)
  1200. X  (define-key calc-mode-map "Z'" 'calc-kbd-pop)
  1201. X  (define-key calc-mode-map "Z=" 'calc-kbd-report)
  1202. X  (define-key calc-mode-map "Z#" 'calc-kbd-query)
  1203. X
  1204. X)
  1205. X
  1206. X
  1207. X
  1208. X
  1209. X;;;; Miscellaneous.
  1210. X
  1211. X(defun calc-record-message (tag &rest args)
  1212. X  (let ((msg (apply 'format args)))
  1213. X    (message "%s" msg)
  1214. X    (calc-record msg tag))
  1215. X  (calc-clear-command-flag 'clear-message)
  1216. X)
  1217. X
  1218. X
  1219. X(defun calc-do-prefix-help (msgs group key)
  1220. X  (if (cdr msgs)
  1221. X      (progn
  1222. X    (setq calc-prefix-help-phase
  1223. X          (if (eq this-command last-command)
  1224. X          (% (1+ calc-prefix-help-phase) (1+ (length msgs)))
  1225. X        0))
  1226. X    (let ((msg (nth calc-prefix-help-phase msgs)))
  1227. X      (message "%s" (if msg
  1228. X                (concat group ": " msg ":"
  1229. X                    (make-string
  1230. X                     (- (apply 'max (mapcar 'length msgs))
  1231. X                    (length msg)) 32)
  1232. X                    "  [MORE]"
  1233. X                    (if key
  1234. X                    (concat "  " (char-to-string key) "-")
  1235. X                      ""))
  1236. X              (format "%c-" key)))))
  1237. X    (setq calc-prefix-help-phase 0)
  1238. X    (if key
  1239. X    (if msgs
  1240. X        (message (concat group ": " (car msgs) ":  "
  1241. X                 (char-to-string key) "-"))
  1242. X      (message (concat group ": (none)  " (char-to-string key) "-")))
  1243. X      (message (concat group ": " (car msgs)))))
  1244. X  (and key
  1245. X       (setq unread-command-char key))
  1246. X)
  1247. X(defvar calc-prefix-help-phase 0)
  1248. X
  1249. X
  1250. X
  1251. X
  1252. X;;;; Commands.
  1253. X
  1254. X
  1255. X;;; General.
  1256. X
  1257. X(defun calc-inverse (&optional n)
  1258. X  "Next Calculator operation is inverse."
  1259. X  (interactive "P")
  1260. X  (calc-wrapper
  1261. X   (calc-set-command-flag 'keep-flags)
  1262. X   (setq calc-inverse-flag (not calc-inverse-flag)
  1263. X     prefix-arg n)
  1264. X   (message (if calc-inverse-flag "Inverse..." "")))
  1265. X)
  1266. X
  1267. X(defun calc-invert-func ()
  1268. X  (setq calc-inverse-flag (not (calc-is-inverse))
  1269. X    calc-hyperbolic-flag (calc-is-hyperbolic)
  1270. X    current-prefix-arg nil)
  1271. X)
  1272. X
  1273. X(defun calc-is-inverse ()
  1274. X  calc-inverse-flag
  1275. X)
  1276. X
  1277. X(defun calc-hyperbolic (&optional n)
  1278. X  "Next Calculator operation is hyperbolic."
  1279. X  (interactive "P")
  1280. X  (calc-wrapper
  1281. X   (calc-set-command-flag 'keep-flags)
  1282. X   (setq calc-hyperbolic-flag (not calc-hyperbolic-flag)
  1283. X     prefix-arg n)
  1284. X   (message (if calc-hyperbolic-flag "Hyperbolic..." "")))
  1285. X)
  1286. X
  1287. X(defun calc-hyperbolic-func ()
  1288. X  (setq calc-inverse-flag (calc-is-inverse)
  1289. X    calc-hyperbolic-flag (not (calc-is-hyperbolic))
  1290. X    current-prefix-arg nil)
  1291. X)
  1292. X
  1293. X(defun calc-is-hyperbolic ()
  1294. X  calc-hyperbolic-flag
  1295. X)
  1296. X
  1297. X
  1298. X(defun calc-evaluate (n)
  1299. X  "Evaluate all variables in the expression on the top of the stack.
  1300. XWith a numeric prefix argument, evaluate each of the top N stack elements."
  1301. X  (interactive "p")
  1302. X  (calc-slow-wrapper
  1303. X   (if (= n 0)
  1304. X       (setq n (calc-stack-size)))
  1305. X   (if (< n 0)
  1306. X       (error "Argument must be positive"))
  1307. X   (calc-with-default-simplification
  1308. X    (calc-pop-push-record-list n "eval" (mapcar 'math-evaluate-expr
  1309. X                        (calc-top-list-n n))))
  1310. X   (calc-handle-whys))
  1311. X)
  1312. X
  1313. X
  1314. X(defun calc-eval-num (n)
  1315. X  "Evaluate numerically the expression on the top of the stack.
  1316. XThis is only necessary when the calculator is in Symbolic mode."
  1317. X  (interactive "P")
  1318. X  (calc-slow-wrapper
  1319. X   (let* ((nn (prefix-numeric-value n))
  1320. X      (calc-internal-prec (cond ((>= nn 3) nn)
  1321. X                    ((< nn 0) (max (+ calc-internal-prec nn)
  1322. X                           3))
  1323. X                    (t calc-internal-prec)))
  1324. X      (calc-symbolic-mode nil))
  1325. X     (calc-with-default-simplification
  1326. X      (calc-pop-push-record 1 "num" (math-evaluate-expr (calc-top-n 1)))))
  1327. X   (calc-handle-whys))
  1328. X)
  1329. X
  1330. X
  1331. X(defun calc-execute-extended-command (n)
  1332. X  "Just like M-x, but inserts \"calc-\" prefix automatically."
  1333. X  (interactive "P")
  1334. X  (let* ((prompt (concat (calc-num-prefix-name n) "M-x "))
  1335. X     (cmd (intern (completing-read prompt obarray 'commandp t "calc-"))))
  1336. X    (setq prefix-arg n)
  1337. X    (command-execute cmd))
  1338. X)
  1339. X
  1340. X
  1341. X(defun calc-num-prefix (n)
  1342. X  "Use the number at the top of stack as the numeric prefix for the next command.
  1343. XWith a prefix, push that prefix as a number onto the stack."
  1344. X  (interactive "P")
  1345. X  (calc-wrapper
  1346. X   (if n
  1347. X       (calc-enter-result 0 "" (prefix-numeric-value n))
  1348. X     (let ((num (calc-top 1)))
  1349. X       (if (math-messy-integerp num)
  1350. X       (setq num (math-trunc num)))
  1351. X       (or (integerp num)
  1352. X       (error "Argument must be a small integer"))
  1353. X       (calc-pop 1)
  1354. X       (setq prefix-arg num)
  1355. X       (message "%d-" num))))    ; a (lame) simulation of the real thing...
  1356. X)
  1357. X
  1358. X
  1359. X(defun calc-more-recursion-depth (n)
  1360. X  "Double the max-lisp-eval-depth value, in case this limit is wrongly exceeded.
  1361. XThis also doubles max-specpdl-size."
  1362. X  (interactive "P")
  1363. X  (let ((n (if n (prefix-numeric-value n) 2)))
  1364. X    (if (> n 1)
  1365. X    (setq max-specpdl-size (* max-specpdl-size n)
  1366. X          max-lisp-eval-depth (* max-lisp-eval-depth n))))
  1367. X  (message "max-lisp-eval-depth is now %d" max-lisp-eval-depth)
  1368. X)
  1369. X
  1370. X(defun calc-less-recursion-depth (n)
  1371. X  "Halve the max-lisp-eval-depth value, in case this limit is too high.
  1372. XThis also halves max-specpdl-size.
  1373. XLower limits are 200 and 600, respectively."
  1374. X  (interactive "P")
  1375. X  (let ((n (if n (prefix-numeric-value n) 2)))
  1376. X    (if (> n 1)
  1377. X    (setq max-specpdl-size
  1378. X          (max (/ max-specpdl-size n) 600)
  1379. X          max-lisp-eval-depth
  1380. X          (max (/ max-lisp-eval-depth n) 200))))
  1381. X  (message "max-lisp-eval-depth is now %d" max-lisp-eval-depth)
  1382. X)
  1383. X
  1384. X
  1385. X(defun calc-time ()
  1386. X  "Push the current time of day on the stack as an HMS form.
  1387. X\(Why?  Why not!)"
  1388. X  (interactive)
  1389. X  (calc-wrapper
  1390. X   (let ((time (current-time-string)))
  1391. X     (calc-enter-result 0 "time"
  1392. X            (list 'mod
  1393. X                  (list 'hms
  1394. X                    (string-to-int (substring time 11 13))
  1395. X                    (string-to-int (substring time 14 16))
  1396. X                    (string-to-int (substring time 17 19)))
  1397. X                  (list 'hms 24 0 0)))))
  1398. X)
  1399. X
  1400. X
  1401. X
  1402. X;;; Incomplete forms.
  1403. X
  1404. X(defun calc-begin-complex ()
  1405. X  "Begin entering a complex number in the Calculator."
  1406. X  (interactive)
  1407. X  (calc-wrapper
  1408. X   (if calc-algebraic-mode
  1409. X       (calc-alg-entry "(")
  1410. X     (calc-push (list 'incomplete calc-complex-mode))))
  1411. X)
  1412. X
  1413. X(defun calc-end-complex ()
  1414. X  "Complete a complex number being entered in the Calculator."
  1415. X  (interactive)
  1416. X  (calc-comma t)
  1417. X  (calc-wrapper
  1418. X   (let ((top (calc-top 1)))
  1419. X     (if (and (eq (car-safe top) 'incomplete)
  1420. X          (eq (nth 1 top) 'intv))
  1421. X     (progn
  1422. X       (while (< (length top) 5)
  1423. X         (setq top (append top '(0))))
  1424. X       (calc-enter-result 1 "..)" (cdr top)))
  1425. X       (if (not (and (eq (car-safe top) 'incomplete)
  1426. X             (memq (nth 1 top) '(cplx polar))))
  1427. X       (error "Not entering a complex number"))
  1428. X       (while (< (length top) 4)
  1429. X     (setq top (append top '(0))))
  1430. X       (if (not (and (math-realp (nth 2 top))
  1431. X             (math-anglep (nth 3 top))))
  1432. X       (error "Components must be real"))
  1433. X       (calc-enter-result 1 "()" (cdr top)))))
  1434. X)
  1435. X
  1436. X(defun calc-begin-vector ()
  1437. X  "Begin entering a vector in the Calculator."
  1438. X  (interactive)
  1439. X  (calc-wrapper
  1440. X   (if calc-algebraic-mode
  1441. X       (calc-alg-entry "[")
  1442. X     (calc-push '(incomplete vec))))
  1443. X)
  1444. X
  1445. X(defun calc-end-vector ()
  1446. X  "Complete a vector being entered in the Calculator."
  1447. X  (interactive)
  1448. X  (calc-comma t)
  1449. X  (calc-wrapper
  1450. X   (let ((top (calc-top 1)))
  1451. X     (if (and (eq (car-safe top) 'incomplete)
  1452. X          (eq (nth 1 top) 'intv))
  1453. X     (progn
  1454. X       (while (< (length top) 5)
  1455. X         (setq top (append top '(0))))
  1456. X       (setcar (cdr (cdr top)) (1+ (nth 2 top)))
  1457. X       (calc-enter-result 1 "..]" (cdr top)))
  1458. X       (if (not (and (eq (car-safe top) 'incomplete)
  1459. X             (eq (nth 1 top) 'vec)))
  1460. X       (error "Not entering a vector"))
  1461. X       (calc-pop-push-record 1 "[]" (cdr top)))))
  1462. X)
  1463. X
  1464. X(defun calc-comma (&optional allow-polar)
  1465. X  "Separate components of a complex number or vector during entry."
  1466. X  (interactive)
  1467. X  (calc-wrapper
  1468. X   (let ((num (calc-find-first-incomplete
  1469. X           (nthcdr calc-stack-top calc-stack) 1)))
  1470. X     (if (= num 0)
  1471. X     (error "Not entering a vector or complex number"))
  1472. X     (let* ((inc (calc-top num))
  1473. X        (stuff (calc-top-list (1- num)))
  1474. X        (new (append inc stuff)))
  1475. X       (if (and (null stuff)
  1476. X        (not allow-polar)
  1477. X        (or (eq (nth 1 inc) 'vec)
  1478. X            (< (length new) 4)))
  1479. X       (setq new (append new
  1480. X                 (if (= (length new) 2)
  1481. X                 '(0)
  1482. X                   (nthcdr (1- (length new)) new)))))
  1483. X       (or allow-polar
  1484. X       (if (eq (nth 1 inc) 'polar)
  1485. X           (setq inc (append '(incomplete cplx) (cdr (cdr inc))))
  1486. X         (if (eq (nth 1 inc) 'intv)
  1487. X         (setq inc (append '(incomplete cplx)
  1488. X                   (cdr (cdr (cdr inc))))))))
  1489. X       (if (and (memq (nth 1 new) '(cplx polar))
  1490. X        (> (length new) 4))
  1491. X       (error "Too many components in complex number"))
  1492. X       (calc-pop-push num new))))
  1493. X)
  1494. X
  1495. X(defun calc-semi ()
  1496. X  "Separate parts of a polar complex number or rows of a matrix during entry."
  1497. X  (interactive)
  1498. X  (calc-wrapper
  1499. X   (let ((num (calc-find-first-incomplete
  1500. X           (nthcdr calc-stack-top calc-stack) 1)))
  1501. X     (if (= num 0)
  1502. X     (error "Not entering a vector or complex number"))
  1503. X     (let ((inc (calc-top num))
  1504. X       (stuff (calc-top-list (1- num))))
  1505. X       (if (eq (nth 1 inc) 'cplx)
  1506. X       (setq inc (append '(incomplete polar) (cdr (cdr inc))))
  1507. X     (if (eq (nth 1 inc) 'intv)
  1508. X         (setq inc (append '(incomplete polar) (cdr (cdr (cdr inc)))))))
  1509. X       (cond ((eq (nth 1 inc) 'polar)
  1510. X          (let ((new (append inc stuff)))
  1511. X        (if (> (length new) 4)
  1512. X            (error "Too many components in complex number")
  1513. X          (if (= (length new) 2)
  1514. X              (setq new (append new '(1)))))
  1515. X        (calc-pop-push num new)))
  1516. X         ((null stuff)
  1517. X          (if (> (length inc) 2)
  1518. X          (if (math-vectorp (nth 2 inc))
  1519. X              (calc-comma)
  1520. X            (calc-pop-push 1
  1521. X                   (list 'incomplete 'vec (cdr (cdr inc)))
  1522. X                   (list 'incomplete 'vec)))))
  1523. X         ((math-vectorp (car stuff))
  1524. X          (calc-comma))
  1525. X         ((eq (car-safe (car-safe (nth (+ num calc-stack-top)
  1526. X                       calc-stack))) 'incomplete)
  1527. X          (calc-end-vector)
  1528. X          (calc-comma)
  1529. X          (let ((calc-algebraic-mode nil))
  1530. X        (calc-begin-vector)))
  1531. X         ((or (= (length inc) 2)
  1532. X          (math-vectorp (nth 2 inc)))
  1533. X          (calc-pop-push num
  1534. X                 (append inc (list (cons 'vec stuff)))
  1535. X                 (list 'incomplete 'vec)))
  1536. X         (t
  1537. X          (calc-pop-push num
  1538. X                 (list 'incomplete 'vec
  1539. X                   (cons 'vec (append (cdr (cdr inc)) stuff)))
  1540. X                 (list 'incomplete 'vec)))))))
  1541. X)
  1542. X
  1543. X(defun calc-dots ()
  1544. X  "Separate parts of an interval form during entry with a \"..\" symbol."
  1545. X  (interactive)
  1546. X  (calc-wrapper
  1547. X   (let ((num (calc-find-first-incomplete
  1548. X           (nthcdr calc-stack-top calc-stack) 1)))
  1549. X     (if (= num 0)
  1550. X     (error "Not entering an interval form"))
  1551. X     (let* ((inc (calc-top num))
  1552. X        (stuff (calc-top-list (1- num)))
  1553. X        (new (append inc stuff)))
  1554. X       (if (not (eq (nth 1 new) 'intv))
  1555. X       (setq new (append '(incomplete intv)
  1556. X                 (if (eq (nth 1 new) 'vec) '(2) '(0))
  1557. X                 (cdr (cdr new)))))
  1558. X       (if (and (null stuff)
  1559. X        (or (eq (nth 1 inc) 'vec)
  1560. X            (< (length new) 5)))
  1561. X       (setq new (append new
  1562. X                 (if (= (length new) 2)
  1563. X                 '(0)
  1564. X                   (nthcdr (1- (length new)) new)))))
  1565. X       (if (> (length new) 5)
  1566. X       (error "Too many components in interval form"))
  1567. X       (calc-pop-push num new))))
  1568. X)
  1569. X
  1570. X(defun calc-find-first-incomplete (stack n)
  1571. X  (cond ((null stack)
  1572. X     0)
  1573. X    ((eq (car-safe (car-safe (car stack))) 'incomplete)
  1574. X     n)
  1575. X    (t
  1576. X     (calc-find-first-incomplete (cdr stack) (1+ n))))
  1577. X)
  1578. X
  1579. X
  1580. X
  1581. X
  1582. X;;; Undo.
  1583. X
  1584. X(defun calc-undo (n)
  1585. X  "Undo the most recent operation in the Calculator.
  1586. XWith a numeric prefix argument, undo the last N operations.
  1587. XWith a negative argument, same as calc-redo.
  1588. XWith a zero argument, same as calc-last-x."
  1589. X  (interactive "p")
  1590. X  (and calc-executing-macro
  1591. X       (error "Use C-x e, not K, to run a keyboard macro that uses Undo."))
  1592. X  (if (<= n 0)
  1593. X      (if (< n 0)
  1594. X      (calc-redo (- n))
  1595. X    (calc-last-x 1))
  1596. X    (calc-wrapper
  1597. X     (if (null (nthcdr (1- n) calc-undo-list))
  1598. X     (error "No further undo information available"))
  1599. X     (setq calc-undo-list
  1600. X       (prog1
  1601. X           (nthcdr n calc-undo-list)
  1602. X         (let ((saved-stack-top calc-stack-top))
  1603. X           (let ((calc-stack-top 0))
  1604. X         (calc-handle-undos calc-undo-list n))
  1605. X           (setq calc-stack-top saved-stack-top))))
  1606. X     (message "Undo!")))
  1607. X)
  1608. X
  1609. X(defun calc-handle-undos (cl n)
  1610. X  (if (> n 0)
  1611. X      (progn
  1612. X    (let ((old-redo calc-redo-list))
  1613. X      (setq calc-undo-list nil)
  1614. X      (calc-handle-undo (car cl))
  1615. X      (setq calc-redo-list (append calc-undo-list old-redo)))
  1616. X    (calc-handle-undos (cdr cl) (1- n))))
  1617. X)
  1618. X
  1619. X(defun calc-handle-undo (list)
  1620. X  (and list
  1621. X       (let ((action (car list)))
  1622. X     (cond
  1623. X      ((eq (car action) 'push)
  1624. X       (calc-pop-stack 1 (nth 1 action)))
  1625. X      ((eq (car action) 'pop)
  1626. X       (calc-push-list (nth 2 action) (nth 1 action)))
  1627. X      ((eq (car action) 'set)
  1628. X       (calc-record-undo (list 'set (nth 1 action)
  1629. X                   (symbol-value (nth 1 action))))
  1630. X       (set (nth 1 action) (nth 2 action)))
  1631. X      ((eq (car action) 'store)
  1632. X       (let ((v (intern (nth 1 action))))
  1633. X         (calc-record-undo (list 'store (nth 1 action)
  1634. X                     (and (boundp v) (symbol-value v))))
  1635. X         (if (y-or-n-p (format "Un-store variable %s? " (nth 1 action)))
  1636. X         (if (nth 2 action)
  1637. X             (set v (nth 2 action))
  1638. X           (makunbound v)))))
  1639. X      ((eq (car action) 'eval)
  1640. X       (calc-record-undo (append (list 'eval (nth 2 action) (nth 1 action))
  1641. X                     (cdr (cdr (cdr action)))))
  1642. X       (apply (nth 1 action) (cdr (cdr (cdr action))))))
  1643. X     (calc-handle-undo (cdr list))))
  1644. X)
  1645. X
  1646. X(defun calc-redo (n)
  1647. X  "Redo a command which was just inadvertently undone."
  1648. X  (interactive "p")
  1649. X  (and calc-executing-macro
  1650. X       (error "Use C-x e, not K, to run a keyboard macro that uses Redo."))
  1651. X  (if (< n 0)
  1652. X      (calc-undo (- n))
  1653. X    (calc-wrapper
  1654. X     (if (null (nthcdr (1- n) calc-redo-list))
  1655. X     (error "Unable to redo"))
  1656. X     (setq calc-redo-list
  1657. X       (prog1
  1658. X           (nthcdr n calc-redo-list)
  1659. X         (let ((saved-stack-top calc-stack-top))
  1660. X           (let ((calc-stack-top 0))
  1661. X         (calc-handle-redos calc-redo-list n))
  1662. X           (setq calc-stack-top saved-stack-top))))
  1663. X     (message "Redo!")))
  1664. X)
  1665. X
  1666. X(defun calc-handle-redos (cl n)
  1667. X  (if (> n 0)
  1668. X      (progn
  1669. X    (let ((old-undo calc-undo-list))
  1670. X      (setq calc-undo-list nil)
  1671. X      (calc-handle-undo (car cl))
  1672. X      (setq calc-undo-list (append calc-undo-list old-undo)))
  1673. X    (calc-handle-redos (cdr cl) (1- n))))
  1674. X)
  1675. X
  1676. X(defun calc-last-x (n)
  1677. X  "Restore the arguments to the last command, without removing its result.
  1678. XWith a numeric prefix argument, restore the arguments of the Nth last
  1679. Xcommand which popped things from the stack."
  1680. X  (interactive "p")
  1681. X  (and calc-executing-macro
  1682. X       (error "Use C-x e, not K, to run a keyboard macro that uses Last X."))
  1683. X  (calc-wrapper
  1684. X   (let ((urec (calc-find-last-x calc-undo-list n)))
  1685. X     (if urec
  1686. X     (calc-handle-last-x urec)
  1687. X       (error "Not enough undo information available"))))
  1688. X)
  1689. X
  1690. X(defun calc-handle-last-x (list)
  1691. X  (and list
  1692. X       (let ((action (car list)))
  1693. X     (if (eq (car action) 'pop)
  1694. X         (calc-pop-push-record-list 0 "lstx"
  1695. X                    (delq 'top-of-stack (nth 2 action))))
  1696. X     (calc-handle-last-x (cdr list))))
  1697. X)
  1698. X
  1699. X(defun calc-find-last-x (ul n)
  1700. X  (and ul
  1701. X       (if (calc-undo-does-pushes (car ul))
  1702. X       (if (<= n 1)
  1703. X           (car ul)
  1704. X         (calc-find-last-x (cdr ul) (1- n)))
  1705. X     (calc-find-last-x (cdr ul) n)))
  1706. X)
  1707. X
  1708. X(defun calc-undo-does-pushes (list)
  1709. X  (and list
  1710. X       (or (eq (car (car list)) 'pop)
  1711. X       (calc-undo-does-pushes (cdr list))))
  1712. X)
  1713. X
  1714. X
  1715. X
  1716. X;;; Arithmetic.
  1717. X
  1718. X(defun calc-min (arg)
  1719. X  "Compute the minimum of the top two elements of the Calculator stack."
  1720. X  (interactive "P")
  1721. X  (calc-slow-wrapper
  1722. X   (calc-binary-op "min" 'calcFunc-min arg))
  1723. X)
  1724. X
  1725. X(defun calc-max (arg)
  1726. X  "Compute the maximum of the top two elements of the Calculator stack."
  1727. X  (interactive "P")
  1728. X  (calc-slow-wrapper
  1729. X   (calc-binary-op "max" 'calcFunc-max arg))
  1730. X)
  1731. X
  1732. X(defun calc-abs (arg)
  1733. X  "Compute the absolute value of the top element of the Calculator stack."
  1734. X  (interactive "P")
  1735. X  (calc-slow-wrapper
  1736. X   (calc-unary-op "abs" 'calcFunc-abs arg))
  1737. X)
  1738. X
  1739. X(defun calc-sqrt (arg)
  1740. X  "Take the square root of the top element of the Calculator stack."
  1741. X  (interactive "P")
  1742. X  (calc-slow-wrapper
  1743. X   (if (calc-is-inverse)
  1744. X       (calc-unary-op "^2" 'calcFunc-sqr arg)
  1745. X     (calc-unary-op "sqrt" 'calcFunc-sqrt arg)))
  1746. X)
  1747. X
  1748. X(defun calc-idiv (arg)
  1749. X  "Compute the integer quotient of the top two elements of the stack."
  1750. X  (interactive "P")
  1751. X  (calc-slow-wrapper
  1752. X   (calc-binary-op "\\" 'calcFunc-idiv arg 1))
  1753. X)
  1754. X
  1755. X(defun calc-fdiv (arg)
  1756. X  "Compute the quotient (in fraction form) of the top two elements of the stack."
  1757. X  (interactive "P")
  1758. X  (calc-slow-wrapper
  1759. X   (calc-binary-op ":" 'calcFunc-fdiv arg 1))
  1760. X)
  1761. X
  1762. X(defun calc-floor (arg)
  1763. X  "Truncate to an integer (toward minus infinity) the top element of the stack.
  1764. XWith Inverse flag, truncates toward plus infinity.
  1765. XWith Hyperbolic flag, represent result in floating-point."
  1766. X  (interactive "P")
  1767. X  (calc-slow-wrapper
  1768. X   (if (calc-is-inverse)
  1769. X       (if (calc-is-hyperbolic)
  1770. X       (calc-unary-op "ceil" 'calcFunc-fceil arg)
  1771. X     (calc-unary-op "ceil" 'calcFunc-ceil arg))
  1772. X     (if (calc-is-hyperbolic)
  1773. X     (calc-unary-op "flor" 'calcFunc-ffloor arg)
  1774. X       (calc-unary-op "flor" 'calcFunc-floor arg))))
  1775. SHAR_EOF
  1776. echo "End of part 3"
  1777. echo "File calc-ext.el is continued in part 4"
  1778. echo "4" > s2_seq_.tmp
  1779. exit 0
  1780.